import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '../store'

// 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (location) {
  return originalPush.call(this, location).catch(err => { })
};

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'home',
    component: () => import('../views/Home.vue')
  },
  {
    path: '/goods',
    name: 'goods',
    component: () => import('../views/Goods.vue')
  },
  {
    path: '/user',
    name: 'user',
    component: () => import('../views/User.vue'),
    children:[
      {
        path:'cart',
        name:'cart',
        component:()=>import('../components/user/Cart.vue')
      },
      {
        path:'my',
        name:'my',
        component:()=>import('../components/user/My.vue')
      }
    ],
    // 单个路由独享守卫
    // beforeEnter: (to, from, next) => {
      //什么时候执行? 当访问 /user 时候执行
      // console.log("进入单个路由独享守卫 beforeEnter");
      // next();

      //需求: 验证进入个人中心页面时,如果没有登录给予提示: 请先登录!
      // if (to.path == '/user') {
      //   let token = localStorage.getItem("x-auth-token");
      //   if (token) {
      //     next();
      //   } else {
      //     //提示:请先登录!
      //     store.dispatch('showToast/asyncChangeToast', {
      //       // 是否显示提示框
      //       isShowToast: true,
      //       // 提示内容
      //       toastMsg: '请先登录!',
      //       // 提示类型 success成功 error错误 warning警告
      //       toastType: "warning",
      //     });
      //   }
      // } else {
      //   // 放行
      //   next();
      // }
    // }

  },
  {
    path: '/order',
    name: 'order',
    component: () => import('../views/Order.vue')
  },
  {
    path: '/free',
    name: 'free',
    component: () => import('../views/Free.vue')
  },
  {
    path: '/details',
    name: 'details',
    component: () => import('../views/Details.vue')
  },
  // 404页面配置，注意：要放在最后一个路由对象且用通配符*
  {
    path:'*',
    name:'error',
    component:()=>import('../components/Error.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

// 全局前置守卫
// router.beforeEach((to, from, next) => {
//   /*
//     to: Route对象: 即将要进入的目标 路由对象
//     from: Route对象: 当前导航正要离开的路由对象
//     next: Function回调函数
//     什么时候执行?  当路由地址发生变化时,导航切换

//     next()   一定要调用该方法,放行进入下一个钩子,才能渲染组件
//     */
//   //  console.log("全局前置守卫 beforeEach:"+to,from);
//   //  next();

// //需求: 验证进入个人中心页面时,如果没有登录给予提示: 请先登录!
// if (to.path == '/user') {
//   let token = localStorage.getItem("x-auth-token");
//   if (token) {
//     next();
//   } else {
//     //提示:请先登录!
//     store.dispatch('showToast/asyncChangeToast', {
//       // 是否显示提示框
//       isShowToast: true,
//       // 提示内容
//       toastMsg: '请先登录!',
//       // 提示类型 success成功 error错误 warning警告
//       toastType: "warning",
//     });
//   }
// } else {
//   // 放行
//   next();
// }
// })


/*vue-router@3.0.7开始之后的版本都会出现：
问题： 重复点击同一个路由出现的报错问题解决
解决方案：
  1.vue-router降版本处理(但不推荐)
  2.直接在编程式路由的push方法最后添加异常捕获,但不做处理
    如：this.push("/home").catch(err=>{})
    但是每个路由都得加，不推荐
  3.直接修改原型方法push(推荐)
  // 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
  const originalPush = VueRouter.prototype.push;
  VueRouter.prototype.push = function(location) {
    return originalPush.call(this, location).catch(err => {})
  };
*/

/*
  路由守卫 / 导航守卫
  作用: 守卫导航
  多种方式: 全局的, 单个路由独享的, 或者组件级的

  全局前置守卫 router.beforeEach(to,from,next)
  路由独享守卫 在路由对象中添加该属性 beforeEnter: (to, from, next)=>{}
    如:
  const routes = [{
    path: '/user',
    name: 'user',
    component: () => import('../views/User.vue'),
    // 单个路由独享守卫
    beforeEnter: (to, from, next) => {
      //什么时候执行? 当访问 /user 时候执行
       console.log("进入单个路由独享守卫 beforeEnter");
       next();
    }
  }]
  理解：路由的钩子函数
 */

/*
组件内守卫
*/

/*
全局前置守卫/路由独享守卫/组件内守卫 区别
理解: 是一个逐渐粒度细化的过程
全局前置守卫: 是指所有组件
              beforeEach()
             路由路径发送变化时候执行
路由独享守卫: 是指某个组件
              beforeEnter()
             当访问某个组件的路由路径时执行
组件内守卫:   是指某个组件中的某一个模块部分
              有三个钩子函数：beforeRouteEnter()   进入该组件的时候执行
                             beforeRouteUpdate()  同个路由地址而参数不同时执行,目的:组件复用
                             beforeRouteLeave()   离开该组件的时候执行
              渲染该组件的时候执行对应的钩子函数
*/            
export default router
